package com.lj.file.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lj.common.utils.EnumUtils;
import com.lj.file.entity.FileDetail;
import com.lj.file.entity.FilePartDetail;
import com.lj.file.enums.UploadStatus;
import com.lj.file.param.FileDetailPageParam;
import com.lj.file.result.FileDetailInfoResult;
import com.lj.file.result.FileDetailPageResult;
import com.lj.mp.standard.StandardService;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.hash.HashInfo;
import org.dromara.x.file.storage.core.upload.FilePartInfo;

import java.io.OutputStream;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 文件记录表 服务类
 * </p>
 *
 * @author lj
 * @since 2025-06-26 16:30:45
 */
public interface FileDetailService extends StandardService<FileDetail> {

    IPage<FileDetailPageResult> page(FileDetailPageParam param);

    FileDetailInfoResult info(Long id);

    void exportExcel(FileDetailPageParam param, OutputStream out);

    /**
     * 将 FileInfo 转为 FileDetail
     */
    default FileDetail toFileDetail(FileInfo info) {
        if (info == null) {
            return null;
        }
        FileDetail detail = BeanUtil.copyProperties(
                info, FileDetail.class, "id", "uploadStatus", "metadata", "userMetadata", "thMetadata", "thUserMetadata", "attr", "hashInfo");

        if (info.getId() != null) {
            detail.setId(NumberUtil.parseLong(info.getId()));
        }
        detail.setUploadStatus(EnumUtils.getByValue(UploadStatus.class, info.getUploadStatus()));
        // 这里手动获 元数据 并转成 json 字符串，方便存储在数据库中
        detail.setMetadata(valueToJson(info.getMetadata()));
        detail.setUserMetadata(valueToJson(info.getUserMetadata()));
        detail.setThMetadata(valueToJson(info.getThMetadata()));
        detail.setThUserMetadata(valueToJson(info.getThUserMetadata()));
        // 这里手动获 取附加属性字典 并转成 json 字符串，方便存储在数据库中
        detail.setAttr(valueToJson(info.getAttr()));
        // 这里手动获 哈希信息 并转成 json 字符串，方便存储在数据库中
        detail.setHashInfo(valueToJson(info.getHashInfo()));
        return detail;
    }

    /**
     * 将 FileDetail 转为 FileInfo
     */
    default FileInfo toFileInfo(FileDetail detail) {
        if (detail == null) {
            return null;
        }
        FileInfo info = BeanUtil.copyProperties(
                detail, FileInfo.class, "id", "uploadStatus", "metadata", "userMetadata", "thMetadata", "thUserMetadata", "attr", "hashInfo");
        if (detail.getId() != null) {
            info.setId(StrUtil.toString(detail.getId()));
        }
        info.setUploadStatus(detail.getUploadStatus() != null ? detail.getUploadStatus().getValue() : null);
        // 这里手动获取数据库中的 json 字符串 并转成 元数据，方便使用
        info.setMetadata(jsonToMetadata(detail.getMetadata()));
        info.setUserMetadata(jsonToMetadata(detail.getUserMetadata()));
        info.setThMetadata(jsonToMetadata(detail.getThMetadata()));
        info.setThUserMetadata(jsonToMetadata(detail.getThUserMetadata()));
        // 这里手动获取数据库中的 json 字符串 并转成 附加属性字典，方便使用
        info.setAttr(jsonToDict(detail.getAttr()));
        // 这里手动获取数据库中的 json 字符串 并转成 哈希信息，方便使用
        info.setHashInfo(jsonToHashInfo(detail.getHashInfo()));
        return info;
    }

    /**
     * 将 FilePartInfo 转成 FilePartDetail
     *
     * @param info 文件分片信息
     */
    default FilePartDetail toFilePartDetail(FilePartInfo info) {
        FilePartDetail detail = new FilePartDetail();
        if (StrUtil.isNotBlank(info.getId())) {
            detail.setId(NumberUtil.parseLong(info.getId()));
        }
        detail.setPlatform(info.getPlatform());
        detail.setUploadId(info.getUploadId());
        detail.setETag(info.getETag());
        detail.setPartNumber(info.getPartNumber());
        detail.setPartSize(info.getPartSize());
        detail.setHashInfo(valueToJson(info.getHashInfo()));
        return detail;
    }

    default FilePartInfo toFilePartInfo(FilePartDetail detail) {
        if (detail == null) {
            return null;
        }
        FilePartInfo filePartInfo = new FilePartInfo();
        if (detail.getId() != null) {
            filePartInfo.setId(StrUtil.toString(detail.getId()));
        }
        filePartInfo.setPlatform(detail.getPlatform());
        filePartInfo.setUploadId(detail.getUploadId());
        filePartInfo.setETag(detail.getETag());
        filePartInfo.setPartNumber(detail.getPartNumber());
        filePartInfo.setPartSize(detail.getPartSize());
        filePartInfo.setHashInfo(jsonToHashInfo(detail.getHashInfo()));
        filePartInfo.setCreateTime(new Date(LocalDateTimeUtil.toEpochMilli(detail.getCreateTime())));
        return filePartInfo;
    }

    /**
     * 将指定值转换成 json 字符串
     */
    default String valueToJson(Object value) {
        if (value == null) return null;
        return JSONUtil.toJsonStr(value);
    }

    /**
     * 将 json 字符串转换成元数据对象
     */
    default Map<String, String> jsonToMetadata(String json) {
        if (StrUtil.isBlank(json)) return null;
        return JSONUtil.toBean(json, new TypeReference<>() {
        }, true);
    }

    /**
     * 将 json 字符串转换成字典对象
     */
    default Dict jsonToDict(String json) {
        if (StrUtil.isBlank(json)) return null;
        return JSONUtil.toBean(json, Dict.class);
    }

    /**
     * 将 json 字符串转换成哈希信息对象
     */
    default HashInfo jsonToHashInfo(String json) {
        if (StrUtil.isBlank(json)) return null;
        return JSONUtil.toBean(json, HashInfo.class);
    }
}
